﻿using Client.Framework;
using Sirenix.OdinInspector;
using Sirenix.Utilities;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;

public class CreateElement : IScriptableObject<CreateElement>
{
    #region 界面可视化参数
    [LabelText("勾选进行编辑")]
    [HorizontalGroup(LabelWidth = 80)]
    public bool IsCanEditor;

    [Button("InitConfig")]
    [HorizontalGroup(MinWidth = 80)]
    public static void InitConfig()
    {
        var typeMap = SerializeConfig.Singleton.typeMap;
        foreach (var item in Singleton.UIExportList)
        {
            var type = ToolsMenu.GetExportType(item.typeName);
            if (type == null) { continue; }
            typeMap[type] = item.element.name;
        }
    }

    [Button("GenerateCS")]
    [HorizontalGroup("Generate")]
    public static void GenerateCSScript()
    {
        ToolsMenu.GenerateCSScript();
    }

    [Button("GenerateLua")]
    [HorizontalGroup("Generate")]
    public static void GenerateLuaScript()
    {
        ToolsMenu.GenerateLuaScript();
    }

    [LabelText("模板表配置")]
    [EnableIf("IsCanEditor")]
    [TableList(ShowIndexLabels = true)]
    public UITemplate[] UITemplateList = new UITemplate[]
    {
        new UITemplate(){name = "CreateCS"},
        new UITemplate(){name = "CreateLua"},
        new UITemplate(){name = "TempCS"},
        new UITemplate(){name = "TempLua"},
    };

    [LabelText("UI路径配置")]
    [EnableIf("IsCanEditor")]
    [TableList(ShowIndexLabels = true)]
    public UIPath[] UIPathList = new UIPath[]
    {
        new UIPath(){name = "LuaPath"},
        new UIPath(){name = "CSPath"},
    };

    [LabelText("UI导出配置")]
    [EnableIf("IsCanEditor")]
    [TableList(ShowIndexLabels = true)]
    public UIExport[] UIExportList = new UIExport[]
    {

    };

    [LabelText("导出规则")]
    [ShowInInspector]
    [DictionaryDrawerSettings()]
    [TableList(ShowIndexLabels = true)]
    public Dictionary<Type, string> ExportRules = new Dictionary<Type, string>();
    #endregion

    [Serializable]
    public class UIElement
    {
        //[ValidateInput("IsValid", "字段名不合法", InfoMessageType.Error)]
        [HideLabel]
        /// <summary>
        /// 名称
        /// </summary>
        public string name;

        public bool IsValid() { return IsValidName(name); }
    }

    /// <summary>
    /// UI标准模板
    /// </summary>
    [Serializable]
    public class UITemplate : UIElement
    {
        /// <summary>
        /// 模板
        /// </summary>
        public TextAsset template;

        /*[FilePath(Extensions = "txt")]
        /// <summary>
        /// 模板文件
        /// </summary>
        public string filePath;*/
    }

    [Serializable]
    public class UIPath : UIElement
    {
        [FolderPath(ParentFolder = "Assets")]
        /// <summary>
        /// 路径
        /// </summary>
        public string path;
    }

    [Serializable]
    public class UIExport
    {
        [ValueDropdown("GetCurrAllType", FlattenTreeView = true, DoubleClickToConfirm = true)]
        /// <summary>
        /// 类型全名
        /// </summary>
        public string typeName;

        public UIElement element;
        /// <summary>
        /// 获取当前所有类型
        /// </summary>
        /// <returns></returns>
        protected IEnumerable GetCurrAllType()
        {
            var allType = GetFilteredTypeList();
            return allType.Select(x => new ValueDropdownItem(x.FullName, x.FullName));
        }
    }

    public static bool IsValidName(string name)
    {
        if (!string.IsNullOrEmpty(name))
        {
            UITools.IsValidName(name);
        }
        return false;
    }

    /// <summary>
    ///  筛选组件
    /// </summary>
    public static IEnumerable<Type> GetFilteredTypeList()
    {
        var types = TypeCache.GetTypesDerivedFrom<MonoBehaviour>();
        types.Where(x => !x.IsAbstract).Where(x => !x.IsInterface);
        types.Where(x => !x.IsGenericTypeDefinition);
        types.AppendWith(typeof(GameObject)); return types;
    }
}